using System.Data;
using Sirenix.OdinInspector;
using Sirenix.Serialization;
using UnityEngine;

/// <summary>决定了一个包含取值范围的数字应当使用什么方式取值</summary>
public enum NumEvaluationMethod
{
    /// <summary>使用固定值</summary>
    UseValue,

    /// <summary>使用区间，取用时随机取值</summary>
    UseRange
}

[System.Serializable]
public struct IntRange
{
    [EnumToggleButtons]
    [LabelText("取值方式")]
    public NumEvaluationMethod EvaluationMethod;

    [LabelText("固定值")]
    [ShowIf("EvaluationMethod", NumEvaluationMethod.UseValue)]
    public int Value;

    [LabelText("取值范围限制")]
    [ShowIfGroup("EvaluationMethod", NumEvaluationMethod.UseRange)]
    public Vector2Int RangeLimitation;

    [MinMaxSlider(nameof(RangeLimitation), true)]
    [LabelText("取值范围")]
    [ShowIfGroup("EvaluationMethod", NumEvaluationMethod.UseRange)]
    public Vector2Int Range;

    public IntRange(
        Vector2Int rangeLimitation,
        Vector2Int range,
        NumEvaluationMethod evaluationMethod = NumEvaluationMethod.UseValue,
        int value = 0
    )
    {
        EvaluationMethod = evaluationMethod;
        Value = value;
        RangeLimitation = rangeLimitation;
        Range = range;
    }

    public IntRange(
        Vector2Int rangeLimitation,
        NumEvaluationMethod evaluationMethod = NumEvaluationMethod.UseValue,
        int value = 0
    )
    {
        EvaluationMethod = evaluationMethod;
        Value = value;
        RangeLimitation = rangeLimitation;
        Range = Vector2Int.zero;
    }

    public IntRange(int value)
    {
        EvaluationMethod = NumEvaluationMethod.UseValue;
        Value = value;
        RangeLimitation = Vector2Int.zero;
        Range = Vector2Int.zero;
    }

    public readonly int GetValue()
    {
        return EvaluationMethod switch
        {
            NumEvaluationMethod.UseValue => Value,
            NumEvaluationMethod.UseRange => Random.Range(Range.x, Range.y),
            _ => Value,
        };
    }

    /// <summary>创建一个初始化范围大小的IntRange</summary>
    public static IntRange CreateWithLimitation(int min, int max) =>
        new(new(min, max), new(min, max), NumEvaluationMethod.UseRange, min);
}

[System.Serializable]
public struct FloatRange
{
    [EnumToggleButtons]
    [LabelText("取值方式")]
    public NumEvaluationMethod EvaluationMethod;

    [LabelText("固定值")]
    [ShowIf("EvaluationMethod", NumEvaluationMethod.UseValue)]
    public float Value;

    [LabelText("取值范围限制")]
    [ShowIfGroup("EvaluationMethod", NumEvaluationMethod.UseRange)]
    public Vector2 RangeLimitation;

    [MinMaxSlider(nameof(RangeLimitation), true)]
    [LabelText("取值范围")]
    [ShowIfGroup("EvaluationMethod", NumEvaluationMethod.UseRange)]
    public Vector2 Range;

    public FloatRange(
        Vector2 rangeLimitation,
        Vector2 range,
        NumEvaluationMethod evaluationMethod = NumEvaluationMethod.UseValue,
        float value = 0
    )
    {
        EvaluationMethod = evaluationMethod;
        Value = value;
        RangeLimitation = rangeLimitation;
        Range = range;
    }

    public FloatRange(
        Vector2 rangeLimitation,
        NumEvaluationMethod evaluationMethod = NumEvaluationMethod.UseValue,
        float value = 0
    )
    {
        EvaluationMethod = evaluationMethod;
        Value = value;
        RangeLimitation = rangeLimitation;
        Range = Vector2.zero;
    }

    public FloatRange(float value)
    {
        Value = value;
        EvaluationMethod = NumEvaluationMethod.UseValue;
        Range = Vector2.zero;
        RangeLimitation = Vector2.zero;
    }

    public readonly float GetValue()
    {
        return EvaluationMethod switch
        {
            NumEvaluationMethod.UseValue => Value,
            NumEvaluationMethod.UseRange => Random.Range(Range.x, Range.y),
            _ => Value,
        };
    }

    /// <summary>创建一个初始化范围大小的FloatRange</summary>
    public static FloatRange CreateWithLimitation(float min, float max) =>
        new(new(min, max), new(min, max), NumEvaluationMethod.UseRange, min);
}
